package spit;

import java.util.ArrayList;
import java.util.Random;

public class SpitPlayer implements Runnable {
	
	ArrayList<CardSlot> myPlayerPiles;
	ArrayList<CardSlot> spitPiles;
	
	CardSlot spitPileThree;
	
	ArrayList<ArrayList> possiblePlays;
	ArrayList<CardSlot> possibleFlipUps;
	ArrayList<CardSlot> possibleSwapToEmpty;
	ArrayList<ArrayList> possibleMatchingSwaps;
	
	ArrayList<CardSlot> rearrangedPiles;
	
	Game myGame;
	
	boolean gameIsOn;
	boolean playStreak;
	int moveCount;
	
	boolean requestingSpit;
	
	public SpitPlayer(Game aGame)
	{
		possiblePlays = new ArrayList<>();
		possibleFlipUps = new ArrayList<>();
		possibleSwapToEmpty = new ArrayList<>();
		possibleMatchingSwaps = new ArrayList<>();
		
		rearrangedPiles = new ArrayList<>();
		
		playStreak = false;
		moveCount = 0;
		
		requestingSpit = false;
		
		myGame = aGame;
		gameIsOn = false;
		
		myPlayerPiles = myGame.getPlayerTwoPiles();
		spitPiles = myGame.getSpitPiles();
		spitPileThree = myGame.getSpitPileThree();
	}
	
	public void startGame()
	{
		
		while( true )
		{

		    gameIsOn = myGame.gameIsOn;
		    //System.out.println("Game is not running!");
			
			while (gameIsOn == true)
			{ 
		
				scanForPlays();
				{
					
					if (possiblePlays.size() > 0)
					{
						requestingSpit = false;
						
						int randomBound = possiblePlays.size();
						Random random = new Random();
						int playIndex = random.nextInt(randomBound);
					
						play(possiblePlays.get(playIndex));
						clearRearrangedPiles();
						
						moveCount = 0;
					
					
					}
					else
					{
						scanForFlipUps();
						{
							if (possibleFlipUps.size() > 0)
							{
								requestingSpit = false;
							
								int randomBound = possibleFlipUps.size();
								Random random = new Random();
								int playIndex = random.nextInt(randomBound);
							
								flip(possibleFlipUps.get(playIndex));
								clearRearrangedPiles();
								
							}
							else
							{
								scanForFillIns();
								{
									if( possibleSwapToEmpty.size() > 0 && getEmptyCardPiles().size() > 0  )
									{
										requestingSpit = false;
										
										int randomBound = possibleSwapToEmpty.size();
										Random random = new Random();
										int swapIndex = random.nextInt(randomBound);
										
										fillIn(possibleSwapToEmpty.get(swapIndex));
										updateRearrangedPiles(possibleSwapToEmpty.get(swapIndex));

									}
									else
									{
										scanForMatching();
										{
											if ( possibleMatchingSwaps.size() > 0 )
											{
												requestingSpit = false;
												
												int randomBound = possibleMatchingSwaps.size();
												Random random = new Random();
												int swapIndex = random.nextInt(randomBound);
												
												matchSwap(possibleMatchingSwaps.get(swapIndex));

											}
											else
											{
												requestingSpit = true;
											}
										}
									}
								}
							}
						}
						
						moveCount++;
						
						if ( moveCount > 4)
						{
							playStreak = false;
						}
					}
				}

				if ( requestingSpit == true )
				{
					myGame.enableSpitButton();
				}
				else
				{
					myGame.disableSpitButton();
				}
			
				myGame.revalidate();
				myGame.repaint();
			
				
				gameIsOn = myGame.gameIsOn;
			}
			

		}
		

	}
	
	public void play(ArrayList<CardSlot> aPossiblePlay)
	{
		Card originalState = aPossiblePlay.get(1).getTopCard();
		
		if ( playStreak == false )
		{
		    try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		    playStreak = true;
		}
		
	    try {
			Thread.sleep(1100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		///spitPile.acceptCard(myPlayerPile.getTopCard());
		
	    Card currentState = null;
	    if ( aPossiblePlay.get(1).getComponentCount() > 0 )
	    {
	    	currentState = aPossiblePlay.get(1).getTopCard();
	    }
	    
	    if ( originalState == currentState && gameIsStillOn() )
	    {

	    	aPossiblePlay.get(1).acceptCard(aPossiblePlay.get(0).getTopCard());
	    	
	    	if ( allMyPilesAreEmpty() )
	    	{
	    		
				myGame.disableSpitButton();
	    		
	    		myGame.setGameIsOn(false);
	    		
	    		if ( myDeckIsEmpty() && spitPileTwoIsEmpty() )
	    		{
	    			System.out.println("I am here for some reason!");
	    			myGame.bringUpEndGamePanel(false);
	    		}
	    		else
	    		{	
	    			System.out.println("Hmmmmmm");
	    			
					myGame.bringUpInterRoundPanel(false);	
									
					chooseDeck(true);
					
					myGame.enablePlayerShuffleButton();

	    		}

	    	}
	    	
	    }
	    else
	    {
	    	System.out.println("GOTTEMS");
	    }

	}
	
	public void flip(CardSlot aPossibleFlip)
	{
		
	    try {
			Thread.sleep(600);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		///spitPile.acceptCard(myPlayerPile.getTopCard());
		
		aPossibleFlip.flipTopCard();
		
		
	}
	
	public void fillIn(CardSlot aPossibleSwapToEmpty)
	{
			
		boolean matchingCardAtTop;
		CardSlot acceptingPile = chooseEmptyCardPile();
		
		do
		{			
			String rankTopCard = "";
			String newRankTopCard = "";
			
		    try {
				Thread.sleep(600);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		    
		    rankTopCard = aPossibleSwapToEmpty.getTopCard().getRank();
		    
		    acceptingPile.acceptCard(aPossibleSwapToEmpty.getTopCard());
		    
		    if ( aPossibleSwapToEmpty.getComponentCount() > 0)	
		    {
		    	newRankTopCard = aPossibleSwapToEmpty.getTopCard().getRank();
		    }
		    
		    if ( rankTopCard.equals(newRankTopCard))
		    {
		    	matchingCardAtTop = true;
		    }
		    else
		    {
		    	matchingCardAtTop = false;
		    }
		}while( matchingCardAtTop == true );

	    
	}
	
	public void matchSwap(ArrayList<CardSlot> aPossibleMatchingSwap)
	{	
		
		boolean matchingCardAtTop;

		do
		{		
			String rankTopCard = "";
			String newRankTopCard = "";
		
			try {
				Thread.sleep(600);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			rankTopCard = aPossibleMatchingSwap.get(1).getTopCard().getRank();
			
			aPossibleMatchingSwap.get(0).acceptCard(aPossibleMatchingSwap.get(1).getTopCard());
					
		    if ( aPossibleMatchingSwap.get(1).getComponentCount() > 0)	
		    {
		    	newRankTopCard = aPossibleMatchingSwap.get(1).getTopCard().getRank();
		    }
		    
		    	
		    if ( rankTopCard.equals(newRankTopCard))
		    {
		    	matchingCardAtTop = true;
		    }
		    else
		    {
		    	matchingCardAtTop = false;
		    }
		}while( matchingCardAtTop == true );
	    
	    
	}
	
	public void scanForPlays()
	{
			possiblePlays.clear();

			for ( CardSlot myPlayerPile : myPlayerPiles)
			{
				if ( myPlayerPile.getComponentCount() > 0)
				{
					for ( CardSlot spitPile : spitPiles)
					{

							if ( spitPile.getComponentCount() > 0)
							{
							
								if ( myPlayerPile.topCardRankNextTo(spitPile.getTopCard()) && myPlayerPile.getTopCard().isFlippedToFront())
								{
									ArrayList<CardSlot> newPlay = new ArrayList<>();
									newPlay.add(myPlayerPile);
									newPlay.add(spitPile);
									possiblePlays.add(newPlay);
									System.out.println("Im in");
								
									//if (notices())
									//{								
									//	spitPile.acceptCard(myPlayerPile.getTopCard());
									//}
								}
							
							}
						}
				
					if ( spitPileThree.getComponentCount() > 0)
					{
					
						if ( myPlayerPile.topCardRankNextTo(spitPileThree.getTopCard()) && myPlayerPile.getTopCard().isFlippedToFront())
						{
							ArrayList<CardSlot> newPlay = new ArrayList<>();
							newPlay.add(myPlayerPile);
							newPlay.add(spitPileThree);
							possiblePlays.add(newPlay);
							System.out.println("Im in theee");
						}
					
					}

				}
				

			}	
			//}
		
	
	}
	
	public void scanForFlipUps()
	{
		possibleFlipUps.clear();
		
		for ( CardSlot myPlayerPile : myPlayerPiles)
		{

				if ( myPlayerPile.getComponentCount() > 0)
				{
					if ( !myPlayerPile.getTopCard().isFlippedToFront())
					{
						possibleFlipUps.add(myPlayerPile);
						
						//if (notices())
						//{								
						//	spitPile.acceptCard(myPlayerPile.getTopCard());
						//}
					}
				}
			
		} 
	}

	public void scanForFillIns()
	{
		possibleSwapToEmpty.clear();
		
		for ( CardSlot myPlayerPile : myPlayerPiles)
		{
			if ( myPlayerPile.getComponentCount() > 0 && !rearrangedPiles.contains(myPlayerPile) && myPlayerPile.getTopCard().isFlippedToFront() )
			{
				possibleSwapToEmpty.add(myPlayerPile);
				
				
			}
			
		} 
	}
	
	public void scanForMatching()
	{
		possibleMatchingSwaps.clear();

		for ( CardSlot aPlayerPile : myPlayerPiles)
		{
			for ( CardSlot anotherPlayerPile : myPlayerPiles)
			{
				
				if ( aPlayerPile.getComponentCount() > 0 && anotherPlayerPile.getComponentCount() > 0)
				{
					if ( !(aPlayerPile == anotherPlayerPile) && aPlayerPile.getTopCard().getRank().equals(anotherPlayerPile.getTopCard().getRank()) )
					{
						ArrayList<CardSlot> newSwap = new ArrayList<>();
						newSwap.add(aPlayerPile);
						newSwap.add(anotherPlayerPile);
						possibleMatchingSwaps.add(newSwap);
						
					}
				}
			
			}
		} 
	}
	
	public ArrayList<CardSlot> getEmptyCardPiles()
	{
		ArrayList<CardSlot> emptySlots = new ArrayList<>();
		
		for ( CardSlot pile : myPlayerPiles )
		{
			if ( pile.getComponentCount() == 0 )
			{
				emptySlots.add(pile);
			}
		}
		
		return emptySlots;
	}
	
	public CardSlot chooseEmptyCardPile()
	{
		ArrayList<CardSlot> emptyCardPiles = getEmptyCardPiles();
		
		System.out.println("Gotach, " + getEmptyCardPiles().size());
		
		int randomBound = emptyCardPiles.size();
		Random random = new Random();
		int emptyIndex = random.nextInt(randomBound);
		
		return emptyCardPiles.get(emptyIndex);
	}
	
	public void updateRearrangedPiles(CardSlot pile)
	{
		rearrangedPiles.add(pile);
	}
	
	public void clearRearrangedPiles()
	{
		rearrangedPiles.clear();
	}
	
	public boolean allMyPilesAreEmpty()
	{
		int emptyPileCount = 0;
		for ( CardSlot pile : myPlayerPiles )
		{
			if ( pile.getComponentCount() == 0 )
			{
				emptyPileCount++;
			}
		}
		
		
		System.out.println("Piles of his that are empty " + emptyPileCount);
		
		if( emptyPileCount == 5 )
		{
			return true;
		}
		else
		{
			return false;
		}		
	}
	
	public boolean myDeckIsEmpty()
	{
		CardSlot myDeck = myGame.getPlayerTwoDeck();
		
		if ( myDeck.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean spitPileTwoIsEmpty()
	{
		CardSlot spitPileTwo = myGame.getSpitPileTwo();
		
		if ( spitPileTwo.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean gameIsStillOn()
	{
		gameIsOn = myGame.gameIsOn;
		
		return gameIsOn;
	}
	
	public void chooseDeck(boolean computerWon)
	{		
		System.out.println("I know I won!");
		
		if ( spitPileThree.getComponentCount() > 0)
		{
			myGame.setPlayerDecksSpit(false);
			
			myGame.addCardInHandToDeck(myGame.getPlayerOneDeck());						
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			for ( CardSlot pile : myGame.getPlayerOnePiles())
			{
				myGame.addDeckToDeck(pile, myGame.getPlayerOneDeck());
				
				try {
					Thread.sleep(600);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			if ( computerWon )
			{
				
				myGame.addDeckToDeck(spitPileThree, myGame.getPlayerOneDeck());
				
			}
			else
			{
				myGame.addDeckToDeck(spitPileThree, myGame.getPlayerTwoDeck());
			}
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			myGame.setGlassInvisible();

		}
		else
		{
			outer: for ( CardSlot aSpitPile : myGame.getSpitPiles() )
			{
				for ( CardSlot anotherSpitPile : myGame.getSpitPiles() )
				{
					if ( aSpitPile != anotherSpitPile ) 
					{
						
						
						if ( aSpitPile.getComponentCount() <= anotherSpitPile.getComponentCount())
						{
							System.out.println("I know I won!");
							
							myGame.setPlayerDecksSpit(false);
							
							
							myGame.addCardInHandToDeck(myGame.getPlayerOneDeck());						
							
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							
							myGame.addDeckToDeck(aSpitPile, myGame.getPlayerTwoDeck() );
							
							try {
								Thread.sleep(600);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							

							
							for ( CardSlot pile : myGame.getPlayerOnePiles())
							{
								myGame.addDeckToDeck(pile, myGame.getPlayerOneDeck());
								
								try {
									Thread.sleep(600);
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
							
							myGame.addDeckToDeck(anotherSpitPile, myGame.getPlayerOneDeck());
							
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							
							myGame.setGlassInvisible();
							
							break outer;
						}
					}
				}
			}
		}
		

	}
	

	
	public boolean notices()
	{
		int notices;
		
		Random random = new Random();
		notices = random.nextInt(3);
		
		
		try { 
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if ( notices == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
		
	}

	@Override
	public void run() {
		startGame();
	}
	
	

}
